package xin.marcher.module.rights.support;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import xin.marcher.module.common.core.JsonResult;
import xin.marcher.module.rights.api.LoginApi;
import xin.marcher.module.rights.domain.request.CheckTokenRequest;

import javax.servlet.http.HttpServletRequest;

/**
 *
 */
public class PermissionSupport {

    private static String AUTHORIZATION_HEADER_NAME = "Authorization";
    private static String SCHEME = "Bearar ";


    private LoginApi loginApi;

    public PermissionSupport(LoginApi loginApi) {
        this.loginApi = loginApi;
    }

    /**
     * 把 token 放到请求头中时校验权限的方法
     * <p>
     * 格式：Authorization: <type> <credentials>
     * the <type> is needed again followed by the credentials,
     * which can be encoded or encrypted depending on which authentication scheme is used.
     * <p>
     * type为"Bearar"的含义
     * https://datatracker.ietf.org/doc/html/rfc6750
     */
    public boolean check(String permissionCode) {
        // 从当前请求中获取token
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String authorizationHeader = request.getHeader(AUTHORIZATION_HEADER_NAME);
        if (StringUtils.isBlank(authorizationHeader) || !StringUtils.startsWith(authorizationHeader, SCHEME)) {
            return false;
        }
        String token = StringUtils.replace(authorizationHeader, SCHEME, "");

        return check(permissionCode, token);
    }

    /**
     * 在 spring mvc MethodHandler 的参数中接收 token 时校验权限的方法
     */
    public boolean check(String permissionCode, String token) {
        CheckTokenRequest checkTokenRequest = new CheckTokenRequest(token, permissionCode);
        JsonResult jsonResult = loginApi.checkToken(checkTokenRequest);
        if (!jsonResult.getSuccess()) {
            return false;
        }
        LoginUserHolder.setLoginUser(((LoginUser) jsonResult.getData()));
        return true;
    }
}
